﻿using System.Collections.Generic;
using NUnit.Framework;

namespace NJabber.Stream.Elements
{
    [TestFixture]
    public class IqStanzaExtensionsTest
    {
        #region HasQuery method tests

        [Test]
        public void HasQuery_ContentHasQueryElement_ReturnTrue()
        {
            IqStanza iq = new IqStanza();
            iq.AddQueryElement("");

            Assert.That(iq.HasQuery(), Is.True);
        }

        [Test]
        public void HasQuery_QueryElementXmlnsEqualsToGivenParameter_ReturnTrue()
        {
            IqStanza iq = new IqStanza();
            iq.AddQueryElement("some-xmlns");

            Assert.That(iq.HasQuery("some-xmlns"), Is.True);
        }

        [Test]
        public void HasQuery_QueryElementXmlnsNotEqualsToGivenParameter_ReturnFalse()
        {
            IqStanza iq = new IqStanza();
            iq.AddQueryElement("some-xmlns");

            Assert.That(iq.HasQuery("some-other-xmlns"), Is.False);
        }

        [Test]
        public void HasQuery_NoQueryElementInContent_ReturnsFalse()
        {
            IqStanza iq = new IqStanza();

            Assert.That(iq.HasQuery(), Is.False);
        }

        #endregion

        #region IsRosterResult tests

        [Test]
        public void IsRosterResult_InvalidQueryNamspaceAndIqType_ReturnFalse()
        {
            IqStanza iq = CreateIq(IqStanzaTypes.Get, "invalid-roster-ns");

            Assert.That(iq.IsRosterResult(), Is.False);
        }

        [Test]
        public void IsRosterResult_InvalidQueryNamspaceAndValidIqType_ReturnFalse()
        {
            IqStanza iq = CreateIq(IqStanzaTypes.Result, "invalid-roster-ns");

            Assert.That(iq.IsRosterResult(), Is.False);
        }

        [Test]
        public void IsRosterResult_ValidQueryNamspaceAndInvalidIqType_ReturnFalse()
        {
            IqStanza iq = CreateIq(IqStanzaTypes.Error, XmppNamespaces.Roster);

            Assert.That(iq.IsRosterResult(), Is.False);
        }

        [Test]
        public void IsRosterResult_ValidQueryNamspaceAndIqType_ReturnTrue()
        {
            IqStanza iq = CreateIq(IqStanzaTypes.Result, XmppNamespaces.Roster);

            Assert.That(iq.IsRosterResult(), Is.True);
        }

        #endregion

        [Test]
        public void HasRosterQuery_QueryElementInRosterNamespace_ReturnsTrue()
        {
            IqStanza iqStanza = CreateIq("", XmppNamespaces.Roster);

            bool hasRosterQuery = iqStanza.HasRosterQuery();
            Assert.That(hasRosterQuery, Is.True);
        }

        [Test]
        public void HasRosterQuery_QueryElementNotInRosterNamespace_ReturnsTrue()
        {
            IqStanza iqStanza = CreateIq("", "not-roster-ns");

            bool hasRosterQuery = iqStanza.HasRosterQuery();
            Assert.That(hasRosterQuery, Is.False);
        }

        [Test]
        public void GetQueryElement_StanzaContainsQueryElement_ReturnsQueryElement()
        {
            IqStanza iqStanza = new IqStanza();
            IqQueryElement queryElement = new IqQueryElement("some-ns");
            iqStanza.AddContentItem(queryElement);

            IqQueryElement actualElement = iqStanza.GetQueryElement();

            Assert.AreEqual(queryElement, actualElement);
        }

        [Test]
        public void GetQueryElement_StanzaNotContainsQueryElement_ReturnsNull()
        {
            IqStanza iqStanza = new IqStanza();

            IqQueryElement actualElement = iqStanza.GetQueryElement();

            Assert.That(actualElement, Is.Null);
        }

        [Test]
        public void GetRosterItemsElements_IqContainsRosterItems_ReturnsRosterItemsElements()
        {
            RosterItemElement[] items = new[] {new RosterItemElement("item1"), new RosterItemElement("item2") };
            IqStanza iqStanza = CreateRosterResultIq(items);

            ICollection<RosterItemElement> actualItems = iqStanza.GetRosterItemsElements();

            CollectionAssert.AreEquivalent(items, actualItems);
        }

        [Test]
        public void GetRosterItemsElements_IqNotContainRosterItems_ReturnsEmptyCollection()
        {
            IqStanza iqStanza = new IqStanza();

            ICollection<RosterItemElement> actualItems = iqStanza.GetRosterItemsElements();

            CollectionAssert.IsEmpty(actualItems);
        }

        public IqStanza CreateRosterResultIq(IEnumerable<RosterItemElement> items)
        {
            IqStanza result = CreateIq(IqStanzaTypes.Result, XmppNamespaces.Roster);
            IqQueryElement queryElement = result.GetQueryElement();
            foreach (RosterItemElement item in items)
            {
                queryElement.AddContentItem(item);
            }
            return result;
        }

        [Test]
        public void IsRosterPush_RosterPushIq_ReturnsTrue()
        {
            IqStanza rosterPush = CreateRosterPushIq();

            Assert.That(rosterPush.IsRosterPush(), Is.True);
        }

        private IqStanza CreateRosterPushIq()
        {
            IqStanza stanza = new IqStanza(IqStanzaTypes.Set);
            stanza.AddQueryElement(XmppNamespaces.Roster)
                  .AddRosterItem("name", "some@jid.com");
            return stanza;
        }

        private IqStanza CreateIq(string type, string queryXmlns)
        {
            IqStanza iqStanza = new IqStanza(type);
            iqStanza.AddQueryElement(queryXmlns);
            return iqStanza;
        }
    }
}